home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2005 October / PCWOCT05.iso / Software / FromTheMag / XAMPP 1.4.14 / xampp-win32-1.4.14-installer.exe / xampp / php / pear / Console / Table.php < prev   
PHP Script  |  2004-03-24  |  9KB  |  312 lines

  1. <?php
  2. // +-----------------------------------------------------------------------+ 
  3. // | Copyright (c) 2002-2003 Richard Heyes                                     | 
  4. // | All rights reserved.                                                  | 
  5. // |                                                                       | 
  6. // | Redistribution and use in source and binary forms, with or without    | 
  7. // | modification, are permitted provided that the following conditions    | 
  8. // | are met:                                                              | 
  9. // |                                                                       | 
  10. // | o Redistributions of source code must retain the above copyright      | 
  11. // |   notice, this list of conditions and the following disclaimer.       | 
  12. // | o Redistributions in binary form must reproduce the above copyright   | 
  13. // |   notice, this list of conditions and the following disclaimer in the | 
  14. // |   documentation and/or other materials provided with the distribution.| 
  15. // | o The names of the authors may not be used to endorse or promote      | 
  16. // |   products derived from this software without specific prior written  | 
  17. // |   permission.                                                         | 
  18. // |                                                                       | 
  19. // | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS   | 
  20. // | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT     | 
  21. // | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | 
  22. // | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT  | 
  23. // | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | 
  24. // | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT      | 
  25. // | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 
  26. // | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 
  27. // | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT   | 
  28. // | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 
  29. // | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  | 
  30. // |                                                                       | 
  31. // +-----------------------------------------------------------------------+ 
  32. // | Author: Richard Heyes <richard@phpguru.org>                           | 
  33. // +-----------------------------------------------------------------------+ 
  34. // 
  35. // $Id: Table.php,v 1.4 2003/03/03 11:37:26 richard Exp $
  36. // 
  37. // Utility for printing tables from cmdline scripts
  38. // 
  39.  
  40. class Console_Table
  41. {
  42.     /**
  43.     * The table headers
  44.     * @var array
  45.     */
  46.     var $_headers;
  47.  
  48.     /**
  49.     * The data of the table
  50.     * @var array
  51.     */
  52.     var $_data;
  53.  
  54.     /**
  55.     * The max number of columns in a row
  56.     * @var integer
  57.     */
  58.     var $_max_cols;
  59.  
  60.     /**
  61.     * The max number of rows in the table
  62.     * @var integer
  63.     */
  64.     var $_max_rows;
  65.  
  66.     /**
  67.     * Lengths of the columns, calculated
  68.     * when rows are added to the table.
  69.     * @var array
  70.     */
  71.     var $_cell_lengths;
  72.  
  73.     /**
  74.     * Some options that configure various
  75.     * things
  76.     * @var array;
  77.     */
  78.     var $_options;
  79.     
  80.     /**
  81.     * How many spaces to use to pad the table
  82.     * @var integer
  83.     */
  84.     var $_padding;
  85.  
  86.     /**
  87.     * Constructor
  88.     */
  89.     function Console_Table()
  90.     {
  91.         $this->_headers      = array();
  92.         $this->_data         = array();
  93.         $this->_cell_lengths = array();
  94.         $this->_max_cols     = 0;
  95.         $this->_max_rows     = 0;
  96.         $this->_padding      = 1;
  97.     }
  98.     
  99.     /**
  100.     * Sets the headers for the columns
  101.     *
  102.     * @param array $headers The column headers
  103.     */
  104.     function setHeaders($headers)
  105.     {
  106.         $this->_headers = $headers;
  107.         $this->_updateRowsCols($headers);
  108.     }
  109.  
  110.     /**
  111.     * Adds a row to the table
  112.     *
  113.     * @param array $row    The row data to add
  114.     * @param array $append Whether to append or prepend the row
  115.     */
  116.     function addRow($row, $append = true)
  117.     {
  118.         $append ? $this->_data[] = array_values($row) : array_unshift($this->_data, array_values($row));
  119.  
  120.         $this->_updateRowsCols($row);
  121.     }
  122.     
  123.     /**
  124.     * Inserts a row after a given row number in the table. If $row_id
  125.     * is not given it will prepend the row.
  126.     *
  127.     * @param array   $row    The data to insert
  128.     * @param integer $row_id Row number to insert before
  129.     */
  130.     function insertRow($row, $row_id = 0)
  131.     {
  132.         array_splice($this->_data, $row_id, 0, array($row));
  133.  
  134.         $this->_updateRowsCols($row);
  135.     }
  136.     
  137.     /**
  138.     * Adds a column to the table
  139.     *
  140.     * @param array   $col_data The data of the column. Can be numeric or associative array
  141.     * @param integer $col_id   The column index to populate
  142.     * @param integer $row_id   If starting row is not zero, specify it here
  143.     */
  144.     function addCol($col_data, $col_id = 0, $row_id = 0)
  145.     {
  146.         foreach ($col_data as $col_cell) {
  147.             $this->_data[$row_id++][$col_id] = $col_cell;
  148.         }
  149.  
  150.         $this->_updateRowsCols();
  151.         $this->_max_cols = max($this->_max_cols, $col_id + 1);
  152.     }
  153.     
  154.     /**
  155.     * Adds data to the table. Argument should be
  156.     * a two dimensional array containing the data
  157.     * to be added.
  158.     *
  159.     * @param array   $data   The data to add to the table
  160.     * @param integer $col_id Optional starting column ID
  161.     * @param integer $row_id Optional starting row ID
  162.     */
  163.     function addData($data, $col_id = 0, $row_id = 0)
  164.     {
  165.         foreach ($data as $row) {
  166.             $starting_col = $col_id;
  167.             foreach ($row as $cell) {
  168.                 $this->_data[$row_id][$starting_col++] = $cell;
  169.             }
  170.             $this->_updateRowsCols();
  171.             $this->_max_cols = max($this->_max_cols, $starting_col);
  172.             $row_id++;
  173.         }
  174.     }
  175.  
  176.     /**
  177.     * Returns the table in wonderful
  178.     * ASCII art
  179.     */
  180.     function getTable()
  181.     {
  182.         $this->_validateTable();
  183.         return $this->_buildTable();
  184.     }
  185.  
  186.     /**
  187.     * Ensures column and row counts are correct
  188.     */
  189.     function _validateTable()
  190.     {
  191.         for ($i=0; $i<$this->_max_rows; $i++) {
  192.             for ($j=0; $j<$this->_max_cols; $j++) {
  193.                 if (!isset($this->_data[$i][$j])) {
  194.                     $this->_data[$i][$j] = '';
  195.                 }
  196.  
  197.                 // Update cell lengths
  198.                 $this->_calculateCellLengths($this->_data[$i]);
  199.             }
  200.             ksort($this->_data[$i]);
  201.         }
  202.         
  203.         ksort($this->_data);
  204.     }
  205.  
  206.     /**
  207.     * Builds the table
  208.     */
  209.     function _buildTable()
  210.     {
  211.         $return = array();
  212.         $rows   = $this->_data;
  213.  
  214.         for ($i=0; $i<count($rows); $i++) {
  215.             for ($j=0; $j<count($rows[$i]); $j++) {
  216.                 if (strlen($rows[$i][$j]) < $this->_cell_lengths[$j]) {
  217.                     $rows[$i][$j] = str_pad($rows[$i][$j], $this->_cell_lengths[$j], ' ');
  218.                 }
  219.             }
  220.             
  221.             $row_begin    = '|' . str_repeat(' ', $this->_padding);
  222.             $row_end      = str_repeat(' ', $this->_padding) . '|';
  223.             $implode_char = str_repeat(' ', $this->_padding) . '|' . str_repeat(' ', $this->_padding);
  224.  
  225.             $return[] = $row_begin . implode($implode_char, $rows[$i]) . $row_end;
  226.         }
  227.  
  228.         $return = $this->_getSeparator() . "\r\n" . implode("\n", $return) . "\r\n" . $this->_getSeparator() . "\r\n";
  229.  
  230.         if (!empty($this->_headers)) {
  231.             $return = $this->_getHeaderLine() . "\r\n" . $return;
  232.         }
  233.  
  234.         return $return;
  235.     }
  236.     
  237.     /**
  238.     * Creates a horizontal separator for header
  239.     * separation and table start/end etc
  240.     *
  241.     */
  242.     function _getSeparator()
  243.     {
  244.         foreach ($this->_cell_lengths as $cl) {
  245.             $return[] = str_repeat('-', $cl);
  246.         }
  247.  
  248.         $row_begin    = '+' . str_repeat('-', $this->_padding);
  249.         $row_end      = str_repeat('-', $this->_padding) . '+';
  250.         $implode_char = str_repeat('-', $this->_padding) . '+' . str_repeat('-', $this->_padding);
  251.  
  252.         $return = $row_begin . implode($implode_char, $return) . $row_end;
  253.         
  254.         return $return;
  255.     }
  256.  
  257.     /**
  258.     * Returns header line for the table
  259.     */
  260.     function _getHeaderLine()
  261.     {
  262.         // Make sure column count is correct
  263.         for ($i=0; $i<$this->_max_cols; $i++) {
  264.             if (!isset($this->_headers[$i])) {
  265.                 $this->_headers[$i] = '';
  266.             }
  267.         }
  268.  
  269.         for ($i=0; $i<count($this->_headers); $i++) {
  270.             if (strlen($this->_headers[$i]) < $this->_cell_lengths[$i]) {
  271.                 $this->_headers[$i] = str_pad($this->_headers[$i], $this->_cell_lengths[$i], ' ');
  272.             }
  273.         }
  274.             
  275.         $row_begin    = '|' . str_repeat(' ', $this->_padding);
  276.         $row_end      = str_repeat(' ', $this->_padding) . '|';
  277.         $implode_char = str_repeat(' ', $this->_padding) . '|' . str_repeat(' ', $this->_padding);
  278.  
  279.         $return[] = $this->_getSeparator();
  280.         $return[] = $row_begin . implode($implode_char, $this->_headers) . $row_end;
  281.  
  282.         return implode("\r\n", $return);
  283.     }
  284.  
  285.     /**
  286.     * Update max cols/rows
  287.     */
  288.     function _updateRowsCols($rowdata = null)
  289.     {
  290.         // Update max cols
  291.         $this->_max_cols = max($this->_max_cols, count($rowdata));
  292.  
  293.         // Update max rows
  294.         ksort($this->_data);
  295.         $this->_max_rows = end(array_keys($this->_data)) + 1;
  296.     }
  297.  
  298.     /**
  299.     * This function given a row of data will
  300.     * calculate the max length for each column
  301.     * and store it in the _cell_lengths array.
  302.     *
  303.     * @param array $row The row data
  304.     */
  305.     function _calculateCellLengths($row)
  306.     {
  307.         for ($i=0; $i<count($row); $i++) {
  308.             $this->_cell_lengths[$i] = max(strlen(@$this->_headers[$i]), @$this->_cell_lengths[$i], strlen(@$row[$i]));
  309.         }
  310.     }
  311. }
  312. ?>